﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ShineTech.Domain.Models.Kanbans;
using ShineTech.Domain.SeedWork;
using ShineTech.Web.Helpers;
using ShineTech.Web.Kanbans.Commands;
using ShineTech.Web.Kanbans.Requests;
using ShineTech.Web.Missons;
using ShineTech.Web.Missons.Commands;
using ShineTech.Web.Missons.Requests;
using ShineTech.Web.Users.Commands;

namespace ShineTech.Web.Kanbans
{
    [Route("api/[controller]")]
    [ApiController]
    public class KanbanController : BaseController
    {
        private readonly IMediator _mediator;

        public KanbanController(IMediator mediator)
        {
            _mediator = mediator;

        }

        [HttpGet("{id}")]
        [ProducesResponseType(typeof(KanbanDTO), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> Get([FromRoute]Guid id)
        {
            KanbanDTO kanban = await _mediator.Send(new KanbanByIdQuery(id));
            if (kanban == null)
                return NotFound();
            return Ok(kanban);
        }



        [HttpGet(Name = "KanbanPageByFiltersPage")]
        [ProducesResponseType(typeof(PageData<KanbanDTO>), StatusCodes.Status200OK)]
        public async Task<IActionResult> GetPage([FromQuery] string name, int pageIndex, int pageSize)
        {
            var user = GetCurrentUser();
            PageData<KanbanDTO> result = await _mediator.Send(new KanbansByFiltersPageQuery(name, user.Id, null, pageIndex, pageSize));
            return Ok(result);
        }


        [HttpPost]
        [ProducesResponseType(typeof(KanbanDTO), StatusCodes.Status201Created)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Post([FromBody] CreateKanbanRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                    return BadRequest(ModelState);
                var currentUser = GetCurrentUser();
                var command = new CreateKanbanCommand(DateTime.Now, request.Name, currentUser.Id, currentUser.Name);
                KanbanDTO kanban = await _mediator.Send(command);
                return Created(string.Empty, kanban);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }

        }
        [HttpPut]
        [ProducesResponseType(typeof(KanbanDTO), StatusCodes.Status201Created)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Put([FromBody] UpdateKanbanRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                    return BadRequest(ModelState);
                var currentUser = GetCurrentUser();
                var command = new UpdateKanbanCommand(request.Id, request.Name, currentUser.Id, currentUser.Name, DateTime.Now);
                KanbanDTO kanban = await _mediator.Send(command);
                return Created(string.Empty, kanban);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }

        }

        [HttpPost("Misson", Name = "Misson")]
        [ProducesResponseType(typeof(MissonDTO), StatusCodes.Status201Created)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Misson([FromBody] CreateMissonRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                    return BadRequest(ModelState);

                var currentUser = GetCurrentUser();
                MissonDTO misson = await _mediator.Send(new CreateMissonCommand(request.KanbanId, request.Name, DateTime.Now, currentUser.Id, currentUser.Name));
                return Created(string.Empty, misson);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        [HttpPost("Share", Name = "Share")]
        [ProducesResponseType(typeof(ShareDTO), StatusCodes.Status201Created)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Share([FromBody] CreateShareRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                    return BadRequest(ModelState);
                var toUser = await _mediator.Send(new UserByEmailQuery(request.Email));
                var sendUser = GetCurrentUser();
                ShareDTO share = await _mediator.Send(new CreateShareCommand(request.KanbanId, toUser.Email, sendUser.Email, sendUser.Id, toUser.Id, DateTime.Now));

                var url = HttpContext.Request.GetRequestBaseUrl();
                return Created(string.Empty, share);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }
        [HttpPost("ShareConfirm", Name = "ShareConfirm")]
        [ProducesResponseType(typeof(ShareDTO), StatusCodes.Status201Created)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Post([FromBody] CreateShareRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                    return BadRequest(ModelState);
                var toUser = await _mediator.Send(new UserByEmailQuery(request.Email));
                var sendUser = GetCurrentUser();
                ShareDTO share = await _mediator.Send(new ConfirmShareCommand(request.KanbanId, toUser.Id));

                var url = HttpContext.Request.GetRequestBaseUrl();
                return Created(string.Empty, url);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        [HttpPost("Delete")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> Delete([FromQuery]Guid id)
        {
            try
            {
                var user = GetCurrentUser();
                await _mediator.Publish(new DeleteKanbanCommand(DateTime.Now, id, user.Id, user.Name));
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

    }
}
